package com.talkology.pilot.manager.service.impl;

import com.talkology.pilot.common.util.DateTimeUtil;
import com.talkology.pilot.database.dao.TalkSalonMgtMapper;
import com.talkology.pilot.database.dao.TeachersTimeMgtMapper;
import com.talkology.pilot.database.dao.WxGroupMapper;
import com.talkology.pilot.database.model.TalkSalonMgt;
import com.talkology.pilot.database.model.TeachersTimeMgt;
import com.talkology.pilot.database.model.WxGroup;
import com.talkology.pilot.manager.model.TalkSalonMgtRest;
import com.talkology.pilot.manager.service.ITalkSalonMgtService;
import com.talkology.pilot.manager.util.ModelParse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

@Service
public class TalkSalonMgtServiceImpl implements ITalkSalonMgtService {
    private static final Logger LOG = LoggerFactory.getLogger(TalkSalonMgtServiceImpl.class);

    @Autowired
    private TeachersTimeMgtMapper timeMgtMapper;
    @Autowired
    private TalkSalonMgtMapper talkSalonMgtMapper;
    @Autowired
    private WxGroupMapper wxGroupMapper;

    @Override
    public TalkSalonMgtRest getInfo(String className) {
        TalkSalonMgt record = talkSalonMgtMapper.selectByName(className);
        List<TeachersTimeMgt> timeMgts =
                timeMgtMapper.selectByFilter(record.getTeacher(), record.getTalkSalonName(), null);
        TalkSalonMgtRest salonMgtRest = ModelParse.parseSalonToRest(record);

        List<String> timeSlots = new ArrayList<>(10);
        timeMgts.forEach(t -> {
            String time = DateTimeUtil.getTimeShortString(t.getAvailableTime());
            timeSlots.add(time);
        });
        salonMgtRest.setTimeSlots(timeSlots);
        return salonMgtRest;
    }

    @Override
    public List<TalkSalonMgtRest> getAll(String subject, String teacher) {
        List<TalkSalonMgt> talkSalonMgts = talkSalonMgtMapper.selectAllByFilter(subject, teacher);
        List<TalkSalonMgtRest> talkSalonMgtRests = new LinkedList<>();
        talkSalonMgts.forEach(record -> {
            List<TeachersTimeMgt> timeMgts =
                    timeMgtMapper.selectByFilter(record.getTeacher(), record.getTalkSalonName(), null);
            TalkSalonMgtRest salonMgtRest = ModelParse.parseSalonToRest(record);

            List<String> timeSlots = new ArrayList<>(10);
            timeMgts.forEach(t -> {
                String time = DateTimeUtil.getTimeShortString(t.getAvailableTime());
                timeSlots.add(time);
            });
            salonMgtRest.setTimeSlots(timeSlots);
            talkSalonMgtRests.add(salonMgtRest);
        });
        return talkSalonMgtRests;
    }

    @Override
    @Transactional
    public void addTalkSalon(TalkSalonMgtRest model) {
        List<String> timeSlots = model.getTimeSlots();
        List<TeachersTimeMgt> timeMgts =
                timeMgtMapper.selectByFilter(model.getTeacher(), null, null);
        String className = model.getTalkSalonName();
        TalkSalonMgt talkSalon = talkSalonMgtMapper.selectByName(className);
        if (talkSalon != null) {
            throw new RuntimeException("Talk salon name cannot repeat.");
        }
        List<TeachersTimeMgt> salonTimeMgts = new ArrayList<>(10);
        timeMgts.forEach(timeMgt -> {
            String time = DateTimeUtil.getTimeShortString(timeMgt.getAvailableTime());
            if (timeSlots.remove(time)) {
                timeMgt.setClassType(className);
                timeMgt.setHasHold(1);
                salonTimeMgts.add(timeMgt);
            }
        });
        if (!timeSlots.isEmpty()) {
            throw new RuntimeException("There have illegal time about " + timeSlots);
        }
        salonTimeMgts.forEach(timeMgt -> timeMgtMapper.updateByPrimaryKey(timeMgt));
        TalkSalonMgt talkSalonMgt = ModelParse.parseSalonToTable(model);
        talkSalonMgtMapper.insert(talkSalonMgt);
        WxGroup wxGroup = wxGroupMapper.selectNewOne();
        wxGroup.setUserName(className);
        wxGroup.setUseFlag(1);
        wxGroupMapper.updateByPrimaryKey(wxGroup);
        LOG.info("Add a new talk salon class: {}", className);
    }

    @Override
    @Transactional
    public void updateTalkSalon(TalkSalonMgtRest model) {
        TalkSalonMgt talkSalonMgt = talkSalonMgtMapper.selectByName(model.getTalkSalonName());
        if (talkSalonMgt.getUsedNum() != 0) {
            throw new RuntimeException("Can't change talk salon information, because already have bookings.");
        }
        List<String> timeSlots = model.getTimeSlots();
        List<TeachersTimeMgt> timeMgts =
                timeMgtMapper.selectByFilter(model.getTeacher(), null, null);
        String className = model.getTalkSalonName();
        List<TeachersTimeMgt> salonTimeMgts = new ArrayList<>(10);
        timeMgts.forEach(timeMgt -> {
            String time = DateTimeUtil.getTimeShortString(timeMgt.getAvailableTime());
            if (timeSlots.remove(time)) {
                timeMgt.setClassType(className);
                timeMgt.setHasHold(1);
                salonTimeMgts.add(timeMgt);
            }
        });
        if (!timeSlots.isEmpty()) {
            throw new RuntimeException("There have illegal time about " + timeSlots);
        }
        salonTimeMgts.forEach(timeMgt -> timeMgtMapper.updateByPrimaryKey(timeMgt));
        talkSalonMgt = ModelParse.parseSalonToTable(model);
        talkSalonMgtMapper.updateByPrimaryKey(talkSalonMgt);
        LOG.info("Update a talk salon class: {}", className);
    }

    @Override
    @Transactional
    public void deleteTalkSalon(String className) {
        TalkSalonMgt talkSalonMgt = talkSalonMgtMapper.selectByName(className);
        if (talkSalonMgt.getUsedNum() != 0) {
            throw new RuntimeException("Can't delete this talk salon, because already have bookings.");
        }
        talkSalonMgtMapper.deleteByPrimaryKey(talkSalonMgt.getIndex());
        LOG.info("Delete a talk salon class: {}", className);
    }

    @Override
    @Transactional
    public String getSalonClassroom(String className) {
        List<WxGroup> wxGroups = wxGroupMapper.getAllByFilter(1, className);
        return wxGroups.get(0).getImageUrl();
    }
}
